<template>
  <el-dialog v-model="state.visible" fullscreen lock-scroll class="Good-full-dialog" :show-close="false" :modal="false">
    <div class="Good-full-dialog-header">
      <div class="header-title">
        <!-- <img src="@/assets/images/Good.png" class="header-logo" /> -->
        <p class="header-txt">· 代码生成</p>
      </div>
      <el-steps
        :active="state.activeStep"
        finish-status="success"
        simple
        :class="'steps steps' + (state.maxStep + 1)"
        v-if="!state.loading"
      >
        <el-step title="基础设置" @click="stepChick(0)" />
        <el-step title="表单设计" @click="stepChick(1)" />
        <el-step title="列表设计" @click="stepChick(2)" v-if="state.maxStep >= 2" />
      </el-steps>
      <div class="options">
        <el-button @click="prev" :disabled="state.activeStep <= 0">{{ $t("message.commonBtn.prev") }}</el-button>
        <el-button @click="next" :disabled="state.activeStep >= state.maxStep || state.loading">
          {{ $t("message.commonBtn.next") }}
        </el-button>
        <el-button type="primary" @click="dataFormSubmit()" :disabled="state.activeStep != state.maxStep">{{
          $t("message.commonBtn.confirm")
        }}</el-button>
        <el-button @click="closeDialog()">{{ $t("message.commonBtn.cancel") }}</el-button>
      </div>
    </div>
    <div class="main" v-loading="state.loading">
      <el-row type="flex" justify="center" align="middle" v-if="!state.activeStep" class="basic-box">
        <el-col :xs="12" :sm="12" :md="12" :lg="12" :xl="10" class="basicForm">
          <el-form
            :model="state.dataForm"
            :rules="rules"
            ref="dataFormRef"
            label-width="80px"
            @submit.prevent
            label-position="right"
          >
            <el-form-item label="模板名称" prop="name">
              <el-input v-model="state.dataForm.name" placeholder="模板名称" maxlength="100"> </el-input>
            </el-form-item>
            <el-form-item label="模板编码" prop="code">
              <el-input v-model="state.dataForm.code" placeholder="模板编码" maxlength="50"> </el-input>
            </el-form-item>
            <el-form-item label="模板分类" prop="category">
              <el-select v-model="state.dataForm.category" placeholder="选择分类">
                <el-option :key="item.value" :label="item.name" :value="item.value!" v-for="item in props.categoryList" />
              </el-select>
            </el-form-item>
            <el-form-item label="模板说明" prop="description">
              <el-input v-model="state.dataForm.description" placeholder="模板说明" type="textarea" :rows="3" />
            </el-form-item>
            <el-form-item label="数据连接">
              <el-select v-model="state.dataForm.configId" placeholder="请选择数据库" @change="onDbChange" clearable>
                <el-option v-for="item in state.dbConfig" :key="item.configId" :value="item.configId" :label="item.name">
                </el-option>
              </el-select>
            </el-form-item>

            <div class="table-actions" @click="openTableSelector">
              <el-button text icon="el-icon-plus">新增一行</el-button>
            </div>
            <ProTable ref="proTableRef" :columns="columns" :data="state.dbTables">
              <template #operation="scope">
                <el-button
                  :icon="Refresh"
                  size="small"
                  text
                  type="success"
                  @click="changeMainTable(scope.row)"
                  v-if="scope.row.tableType == 'sub'"
                >
                  切换主表
                </el-button>
                <el-button :icon="Delete" size="small" text type="danger" @click="delItem(scope.row.id, scope.$index)">
                  {{ $t("message.commonBtn.delete") }}
                </el-button>
              </template>
            </ProTable>
          </el-form>
        </el-col>
      </el-row>
      <template v-if="state.activeStep == 1">
        <Generator ref="generatorRef" />
      </template>
      <!-- <template v-if="state.activeStep==2">
        <columnDesign ref="columnDesign" :columnData="columnData" :appColumnData="appColumnData"
          :modelType="state.dataForm.type" :webType="state.dataForm.webType" :dbType="dbType" />
      </template>-->
    </div>
    <TableForm ref="tableFormRef" @select="handleAddTable" />
  </el-dialog>
</template>

<script lang="tsx" setup>
import { defineAsyncComponent, reactive, ref } from "vue";
import codeGenApi from "@/api-services/apis/generator/codeGenApi";
import codeGenFormConfigApi from "@/api-services/apis/generator/codeGenFormConfigApi";
import { DictData } from "@/api-services/models/system";
import { ElMessage, ElOption, ElSelect } from "element-plus";
import { CodeGenData, DbConfig, DbTableInfo, FieldInfo, TableFields } from "@/api-services/models/codeGen";
import { CodeGenTableInfo } from "@/api-services/models/codeGen/CodeGenTableInfo";
import { CodeGenDataFormConfig } from "@/api-services/models/codeGen/CodeGenFormConfig";
import { useFormData } from "@/components/Form/stores/formStore";
import { Delete, Refresh } from "@element-plus/icons-vue";
import ProTable from "@/components/ProTable/index.vue";
import { ColumnProps } from "@/components/ProTable/interface";
const TableForm = defineAsyncComponent(() => import("../component/TableForm.vue"));
const Generator = defineAsyncComponent(() => import("@/components/Form/index/Home.vue"));
const proTableRef = ref();
const dataFormRef = ref();
const generatorRef = ref();
const tableFormRef = ref();
const stores = useFormData();
const props = defineProps({
  categoryList: Array<DictData.SysDictData> //模板分类
});
const state = reactive({
  activeStep: 0,
  maxStep: 2,
  loading: false,
  visible: false,
  dbTables: [] as Array<CodeGenTableInfo>, //数据表数组
  dataForm: {} as CodeGenData, //模板基本信息
  detailData: {} as CodeGenDataFormConfig, //
  dbConfig: [] as Array<DbConfig>, //数据库连接信息
  tableFields: [] as Array<TableFields>, //数据表字段
  mainTable: "", //主表
  mainTableFields: [] as Array<FieldInfo> //主表字段
});
const columns: ColumnProps<CodeGenTableInfo>[] = [
  { prop: "name", label: "名称" },
  {
    prop: "tableType",
    label: "类别",
    render: scope => {
      let table = "主表";
      let type = "success";
      if (scope.row.tableType == "sub") {
        table = "子表";
        type = "warning";
      }
      return <el-tag type={type}>{table}</el-tag>;
    }
  },
  {
    prop: "description",
    label: "描述"
  },
  {
    prop: "foreignKey",
    label: "关联外键",
    render: scope => {
      if (!state.dbTables || state.dbTables.length == 1) {
        return;
      }
      if (scope.row.tableType == "sub") {
        let fields = state.tableFields.filter(t => t.tableName == scope.row.name)[0];
        return (
          <ElSelect v-model={scope.row.foreignKey} placeholder="请选择">
            {fields.fieldInfos.map(option => (
              <ElOption key={option.columnName} label={option.columnDescription} value={option.columnName} />
            ))}
          </ElSelect>
        );
      }
    }
  },
  {
    prop: "relationKey",
    label: "关联主键",
    render: scope => {
      if (!state.dbTables || state.dbTables.length == 1) {
        return;
      }
      if (scope.row.tableType == "main") {
        let fields = state.tableFields.filter(t => t.tableName == scope.row.name)[0];
        return (
          <ElSelect v-model={scope.row.relationKey} placeholder="请选择">
            {fields.fieldInfos.map(option => (
              <ElOption key={option.columnName} label={option.columnDescription} value={option.columnName} />
            ))}
          </ElSelect>
        );
      }
    }
  },
  { prop: "operation", label: "操作", fixed: "right", width: 200 }
];
const openDialog = (baseInfo: any) => {
  state.visible = true;
  state.loading = true;
  state.dataForm = JSON.parse(JSON.stringify(baseInfo));
  initData();
  state.loading = false;
};
const closeDialog = () => {
  state.visible = false;
};
//界面打开后初始化操作
const initData = () => {
  state.activeStep = 0;
  state.dbTables = [];
  state.maxStep = 2;
  getDbConfig();
  getDetailData();
};
//上一步
const prev = () => {
  state.activeStep -= 1;
};
const stepChick = (key: number) => {
  if (state.activeStep <= key) return;
  state.activeStep = key;
};
const getDbConfig = async () => {
  let res = await codeGenApi.getDbConfig();
  state.dbConfig = res.data.data;
};
const getDetailData = async () => {
  if (!state.dataForm.id) return;
  let detail = await codeGenFormConfigApi.getDetailData({ id: state.dataForm.id });
  state.detailData = detail.data.data;
  let tableNames = state.detailData.tableInfoList.map(item => item.name);
  //查询数据表字段
  let input = { ConfigId: state.dataForm.configId, TableNames: tableNames.join(",") };
  let tableFields = await codeGenApi.getTableFields(input);
  state.tableFields = tableFields.data.data;
};
//数据库切换时，数据表需要清空
const onDbChange = async () => {
  state.dbTables = [];
};

const next = () => {
  if (state.activeStep == 0) {
    dataFormRef.value.validate(async (valid: boolean) => {
      if (valid) {
        state.activeStep += 1;
        //存储数据表、字段
        stores.setAllTable(state.dbTables);
        stores.setTableFields(state.tableFields);
        stores.setDrawingList(state.detailData.formData);
      }
    });
  } else if (state.activeStep == 1) {
    state.activeStep += 1;
  } else {
    //todo
    state.activeStep += 1;
  }
};
//切换主表
const changeMainTable = (row: CodeGenTableInfo) => {
  state.mainTable = row.name;

  state.dbTables.forEach(item => {
    if (row.name == item.name) {
      item.tableType = "main";
      item.relationTableName = undefined;
      item.foreignKey = undefined;
      item.relationKey = undefined;
    } else {
      //不是主表的，外键和关联主键都需要重新设置
      item.tableType = "sub";
      item.relationTableName = row.name;
      item.foreignKey = undefined;
      item.relationKey = undefined;
    }
  });
};
//删除一条数据表
const delItem = (row: any, index: number) => {
  state.dbTables.splice(index, 1);
};
//数据校验
const rules = {
  name: [{ required: true, message: "模板名称不能为空", trigger: "blur" }],
  code: [{ required: true, message: "模板编码不能为空", trigger: "blur" }],
  category: [{ required: true, message: "模板分类不能为空", trigger: "change" }]
};

const openTableSelector = () => {
  if (state.dataForm.configId === undefined || state.dataForm.configId == "") {
    ElMessage.error("请先选择数据库");
    return;
  }
  tableFormRef.value.openDialog(state.dataForm.configId);
};
//处理新增的数据表
const handleAddTable = async (tables: Array<DbTableInfo>) => {
  if (tables.length == 0) return;
  let tableNames = [] as Array<string>;
  let setMainTable = false; //是否需要设置主表
  if (state.dbTables.length > 0) {
    let dbTableName = state.dbTables.map(item => item.name);
    tables.forEach(item => {
      if (dbTableName.indexOf(item.name) > -1) return;
      tableNames.push(item.name);
    });
  } else {
    //当dbTables没有数据时，才设置主表
    tableNames = tables.map(item => item.name);
    setMainTable = true;
    //将第一个表设为主表
    state.mainTable = tableNames[0];
  }
  //查询数据表字段
  let input = { ConfigId: state.dataForm.configId, TableNames: tableNames.join(",") };
  let res = await codeGenApi.getTableFields(input);
  let tableFields = res.data.data;
  if (tableFields.length == 0) return;

  tableFields.forEach((item: TableFields) => {
    let data = {} as CodeGenTableInfo;
    //如果需要设置主表，根据之前记录的主表名设置
    if (setMainTable && item.tableName == state.mainTable) {
      data.tableType = "main";
      state.mainTableFields = item.fieldInfos;
    } else {
      data.tableType = "sub"; //其它都设置为子表
      data.relationTableName = state.mainTable; //关联主表
    }
    let t = tables.filter(t => t.name == item.tableName)[0];
    data.name = item.tableName;
    data.description = t.description;
    state.dbTables.push(data);
    state.tableFields.push(item);
  });
};
const dataFormSubmit = () => {
  console.log(1);
};
defineExpose({ openDialog });
</script>
<style lang="scss" scoped>
@import "@/styles/good_common.scss";
:deep(.table-main) {
  height: 420px;
  max-height: 420px !important;
}
</style>
